﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Media.Imaging;


namespace ExifToFileName
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        public string GetDate(FileInfo f)
        {
            FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.None);
            try
            {
                BitmapSource img = BitmapFrame.Create(fs);
                BitmapMetadata md = (BitmapMetadata)img.Metadata;
                if (md == null)
                    return null;
                else
                    return md.DateTaken;
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR GetDate: " + ex.Message + "\r\n");
                return null;
            }
            finally
            {
                fs.Close();
            }
        }

        struct MyFileStruct
        {
            public string filePaths;
            public string newfilePaths;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {


                txtLog.Clear();

                string folder = null;
                string[] appoFiles = null;
                string startupPath = Application.StartupPath;
                using (FolderBrowserDialog dialog = new FolderBrowserDialog())
                {
                    dialog.Description = "Open a folder which contains the images";
                    dialog.ShowNewFolderButton = false;
                    dialog.RootFolder = Environment.SpecialFolder.MyComputer;
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        folder = dialog.SelectedPath;
                        string[] appoFiles1 = null;
                        string[] appoFiles2 = null;
                        string[] appoFiles3 = null;
                        string[] appoFiles4 = null;
                        string[] appoFiles5 = null;
                        string[] appoFiles6 = null;
                        if (checkBox1.Checked)
                            appoFiles1 = Directory.GetFiles(@folder, "*.jpg");
                        if (checkBox2.Checked)
                            appoFiles2 = Directory.GetFiles(@folder, "*.bmp");
                        if (checkBox3.Checked)
                            appoFiles3 = Directory.GetFiles(@folder, "*.png");
                        if (checkBox4.Checked)
                            appoFiles4 = Directory.GetFiles(@folder, "*.3gp");
                        if (checkBox5.Checked)
                            appoFiles5 = Directory.GetFiles(@folder, "*.mp4");
                        if (checkBox6.Checked)
                            appoFiles6 = Directory.GetFiles(@folder, "*.avi");

                        appoFiles = appoFiles1.Concat(appoFiles2).Concat(appoFiles3).Concat(appoFiles4).Concat(appoFiles5).Concat(appoFiles6).ToArray();
                    }
                }

                if (appoFiles == null)
                {
                    MessageBox.Show("No image file found!", "No found");
                    return;
                }

                txtLog.AppendText("Start Process: " + folder + "\r\n");

                List<MyFileStruct> files = new List<MyFileStruct>();

                int count = 0;
                progressBar1.Value = 0;
                progressBar1.Maximum = appoFiles.Count();
                foreach (var filep in appoFiles)
                {
                    progressBar1.Value++;
                    MyFileStruct appoST = new MyFileStruct();

                    System.IO.FileInfo TheFile = new FileInfo(filep);
                    var dirp = TheFile.Directory;

                    string appoEXIFDate = null;
                    if ((TheFile.Extension != ".avi") && (TheFile.Extension != ".3gp") && (TheFile.Extension != ".mp4"))
                    {
                        appoEXIFDate = GetDate(TheFile);
                    }
                    DateTime appoDT;
                    if (appoEXIFDate != null)
                        appoDT = Convert.ToDateTime(appoEXIFDate);
                    else
                        appoDT = TheFile.LastWriteTime;

                    string ext = TheFile.Extension;
                    //TheFile = null;

                    string NewFileName = dirp + "\\" + appoDT.Year.ToString("0000") + "-" + appoDT.Month.ToString("00") + "-" + appoDT.Day.ToString("00") + " " +
                                        appoDT.Hour.ToString("00") + "." + appoDT.Minute.ToString("00") + "." + appoDT.Second.ToString("00") + ext;

                    appoST.filePaths = filep;
                    appoST.newfilePaths = NewFileName;
                    files.Add(appoST);
                    try
                    {
                        if (!System.IO.File.Exists(appoST.newfilePaths))
                            if (appoST.filePaths != appoST.newfilePaths)
                            {
                                System.IO.File.Move(appoST.filePaths, appoST.newfilePaths);
                                count++;
                                txtLog.AppendText("Count: " + count + " - " + appoST.filePaths + " -> " + appoST.newfilePaths + "\r\n");
                            }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("ERROR: " + ex.Message + ": " + count + " - " + appoST.filePaths + " -> " + appoST.newfilePaths + "\r\n");
                        txtLog.AppendText("ERROR: " + ex.Message + ": " + count + " - " + appoST.filePaths + " - " + appoST.newfilePaths + "\r\n");
                        return;
                    }
                }
                MessageBox.Show("Done successfull: " + files.Count() + " image processed / " + count + " image renamed!" + "\r\n");
                txtLog.AppendText("Done successfull: " + files.Count() + " image processed / " + count + " image renamed!" + "\r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR btnStart_Click: " + ex.Message + "\r\n");
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            this.Text = Application.ProductName + " v" + Application.ProductVersion;

            txtLog.AppendText(">Ready to run, press start and then select folder with images to rename." + "\r\n");
            txtLog.AppendText("" + "\r\n");
            txtLog.AppendText("Copyright Notice" + "\r\n");
            txtLog.AppendText("----------------" + "\r\n");
            txtLog.AppendText(Application.ProductName + " is the sole Copyright of " + Application.CompanyName + ", all rights reserved." + "\r\n");
            txtLog.AppendText("" + "\r\n");
            txtLog.AppendText("Licence Agreement" + "\r\n");
            txtLog.AppendText("=================" + "\r\n");
            txtLog.AppendText("You should read the following terms and conditions before using this software." + "\r\n");
            txtLog.AppendText("YOUR INSTALLATION AND/OR USE OF THIS SOFTWARE INDICATES YOUR ACCEPTANCE OF THIS LICENCE AGREEMENT AND WARRANTY." + "\r\n");
            txtLog.AppendText("You may not alter this software in any way.  " + "\r\n");
            txtLog.AppendText("You may not decompile, reverse engineer, disassemble or otherwise reduce this software to a human perceivable form.  You may not modify or rent for profit this software, or create derivative works based upon this software." + "\r\n");
            txtLog.AppendText("You may not publicise or distribute any algorithms or information used by this software without permission of the author/s." + "\r\n");
            txtLog.AppendText("You hereby agree to indemnify, hold harmless, and defend the author(s) from and against any and all liabilities, damages, losses, costs and expenses (including reasonable legal fees) arising from or related to any claim, action, proceeding or allegation that arises or results, either directly or indirectly, from the use and distribution of this software. " + "\r\n");
            txtLog.AppendText("You may terminate this Licence at any time by deleting or destroying the Software, documentation and all copies.  No Licence fee is refundable.  We may terminate this Licence at any time if you are found to be in breach of any of these terms." + "\r\n");
            txtLog.AppendText("Notwithstanding any other provision in this Licence, a person who is not a party to this Licence has no right under the Contracts (Rights of Third Parties) Act 1999 (the 'Act') to rely upon or enforce any term of this Licence.  Nothing in this Licence shall affect any right or remedy of a third party which exists or is available apart from that Act." + "\r\n");
            txtLog.AppendText("" + "\r\n");
            txtLog.AppendText("Warranty Disclaimer" + "\r\n");
            txtLog.AppendText("-------------------" + "\r\n");
            txtLog.AppendText("THE SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND.TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE AUTHOR/S FURTHER DISCLAIM ALL WARRANTIES, INCLUDING WITH OUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANT ABILITY, FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OF INFORMATION AND NON INFRINGEMENT. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THIS SOFTWARE AND DOCUMENTATION REMAINS WITH THE RECIPIENT. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE AUTHOR/S BE LIABLE FOR ANY CONSEQUENTIAL, INCIDENTAL, DIRECT, INDIRECT, SPECIAL, PUNITIVE OR OTHER DAMAGES OR COSTS WHATSOEVER (INCLUDING, WITH OUT LIMITATION, DAMAGES OR COSTS FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION OR OTHER PECUNIARY LOSS) ARISING OUT OF THIS AGREEMENT OR THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF THE AUTHOR/S OF THE SOFTWARE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE AUTHOR/S DO NOT TAKE ANY RESPONSIBILITY AGAINST ANY DAMAGE THIS SOFTWARE MAY DO TO YOUR SYSTEM OR ANOTHER. OUR MAXIMUM AGGREGATE LIABILITY IN RESPECT OF ANY CLAIM OR SERIES OF CLAIMS SHALL BE LIMITED TO THE LICENCE FEE PAID BY YOU, IF ANY, FOR THE SOFTWARE. " + "\r\n");
            txtLog.AppendText("THE SOFTWARE IS NOT WARRANTED TO BE FAULT-TOLERANT, AND IS NOT INTENDED FOR THE DESIGN, CONSTRUCTION, MAINTENANCE, OPERATION, CONTROL, OR ANY OTHER USE IN CONNECTION WITH HIGH RISK SYSTEMS. WE SPECIFICALLY DISCLAIM ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR PURPOSE IN CONNECTION WITH HIGH RISK SYSTEMS." + "\r\n");
            txtLog.AppendText("‘High Risk Systems’ means systems in environments requiring fail-safe performance (such as nuclear facilities, aircraft navigation or communication systems, air traffic control, direct life support machines, storm chasing or weapons systems), in which the failure of the software could lead directly to death, personal injury, or severe physical or environmental damage. You agree that you will not use the software for any purpose in connection with High Risk Systems." + "\r\n");
            txtLog.AppendText("ALTHOUGH the author/s DO NOT WARRANT THAT THE SOFTWARE SUPPLIED HEREUNDER SHALL BE FREE FROM ALL KNOWN VIRUSES WE HAVE USED COMMERCIALLY REASONABLE EFFORTS TO CHECK FOR THE MOST COMMONLY KNOWN VIRUSES. YOU ARE NEVERTHELESS SOLELY RESPONSIBLE FOR VIRUS SCANNING THE SOFTWARE." + "\r\n");
            txtLog.AppendText("" + "\r\n");

        }
    }
}
